package org.oy.sealogger.ds.nmea;

import java.io.IOException;
import java.io.InputStream;

import org.apache.log4j.Logger;
import org.oy.sealogger.common.Config;
import org.oy.sealogger.ds.InputAnalyser;

/**
 * Input analyser for NMEA0183 data.
 * @author riku
 *
 */
public class NMEA0183InputAnalyser implements InputAnalyser {

	// This code prefix should be produced by all NMEA compatible GPS devices so we'll look for it.
	// TODO: There ARE some GPS devices that don't use the $GP prefixes, so fix this if needed.
	private static final String NMEA_ESSENTIAL_FIX = "$GP";
	private static Logger log = Config.getLogger();
	// Codes below are used for determining the NMEA0183 version
	//private static final String NMEA_RECOMMENDED_MINIMUM = "$GPRMC";

	/**
	 * Analyses input stream
	 * @return NEMA0183Metadata object including information about the NMEA input stream
	 * @throws NMEA0183Exception Exception is thrown if the input is not recognizable NMEA0183 stream
	 */
	public NMEA0183Metadata analyse(InputStream in) {
		
		log.debug("Analysing input ...");
		
		boolean codeFound = false;
		boolean readMore = true;
		
		char[] buffer = new char[NMEA_ESSENTIAL_FIX.length()];
		int i = 0;
		int tries = 512;

		try {
			Thread.sleep(Config.DEVICE_DATA_WAIT_TIME); // Wait for some data to appear
		} catch (InterruptedException e) {
			log.error(e);
		}
		
		while(readMore && i < buffer.length && tries > 0) {
			try {
				if(in.available() <= 0) {
					--tries;
					continue;
				}
				
				int c = in.read();
				
				if(c < 0 || 
						c < 0 || 
						c > 255 || 
						Character.isSpaceChar((char)c) ||
						(i == 0 && ((char)c) != '$')) {
					--tries;
					continue;
				}
				
				buffer[i++] = (char)c;
				
				if(i == buffer.length) {
					String s = new String(buffer);
					codeFound = s.equals(NMEA_ESSENTIAL_FIX);
					readMore = !codeFound;
					log.debug(s + (codeFound ? " is NMEA0183" : " doesn't look like NMEA0183"));
					i = 0;
				}
				
				if(tries == 0)
					readMore = false;
				
			} catch(IOException e) {
				log.error(e);
			}
		}
		
		return new NMEA0183Metadata(codeFound);
	}
}
